home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / winlib.lzh / WINLIB / EXTNDOBJ.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-03  |  49.7 KB  |  1,619 lines

  1. /********************************************************************
  2.  *                                                                    *
  3.  *    Extended resource objects module                                *
  4.  *                                                                    *
  5.  *    Copyright (c) Clever Bits and Bitgate Software 1993 - 1994        *
  6.  *    All Rights Reserved.                                            *
  7.  *                                                                    *
  8.  *    This modules deals with all extended objects plus all "fixing"    *
  9.  *    of resource objects, eg. scaling of icons and bitmaps to fit    *
  10.  *    resolutions.                                                    *
  11.  *                                                                    *
  12.  ********************************************************************
  13.  *                                                                    *
  14.  *    Update log:                                                        *
  15.  *                                                                    *
  16.  *    [14.7.93 - 31.10.93] Ken Hollis                                    *
  17.  *        pb_textout            - added several different drawing styles*
  18.  *    [31.10.93 - 18.3.94] Karl A. 0ygard and Ken Hollis                *
  19.  *        (global)            - worked further on EObTs                *
  20.  *                            - added more images for your pleasure    *
  21.  *                            - changed some images, added animation    *
  22.  *                            - changed box, circle, and cycle buttons*
  23.  *                            - added the DROPDOWN icon                *
  24.  *                            - added clipping to ALL graphics        *
  25.  *        fix_object            - fixed a size problem with CUSTOM        *
  26.  *        pb_doobject            - fixed colors for four-color monitors    *
  27.  *                            - fixed L_GENEVA type to look correct    *
  28.  *                            - added inverted hotkey option            *
  29.  *                            - added custom disabled state            *
  30.  *        draw_custbutton        - optimized and fixed some incoherence    *
  31.  *                            - added CUSTBTN and CYCLEBTN looks        *
  32.  *                            - added image copy within routine        *
  33.  *                            - added switching for optimizations        *
  34.  *                            - added DROPDOWN type                    *
  35.  *                            - added color icon stuff                *
  36.  *        draw_boxframe        - added for grouping related items        *
  37.  *                            - added boxed title (with colors)        *
  38.  *                            - added WHITEBACK check for 3D effect    *
  39.  *                            - updated WHITEBACK drawing method        *
  40.  *        draw_menuline        - added for menu separators (better)    *
  41.  *                                                                    *
  42.  ********************************************************************/
  43.  
  44. #include <aes.h>
  45. #include <vdi.h>
  46. #include <stdlib.h>
  47. #include <stddef.h>
  48. #include <string.h>
  49. #include <ctype.h>
  50.  
  51. #include "winlib.h"
  52.  
  53. #ifdef __TURBOC__
  54. #pragma warn -pia
  55. #endif
  56.  
  57. #ifndef __EXTENDEDOBJ__
  58. #define __EXTENDEDOBJ__
  59. #endif
  60.  
  61. static int *cycle_on, *cycle_off, *box_on, *box_off, *radio_on,
  62.         *radio_off, *up_on, *up_off, *down_on, *down_off, *left_on,
  63.         *left_off, *right_on, *right_off, *dropdown_on, *dropdown_off;
  64. int draw3dtype;
  65.  
  66. static int radio_hi_on[] =
  67. {
  68.     0x0000, 0x03E0, 0x0FF8, 0x1C0C, 0x3942, 0x32A2, 0x6551, 0x6AA9, 
  69.     0x6551, 0x6AA9, 0x6551, 0x22A2, 0x3142, 0x1004, 0x0C18, 0x03E0, 
  70.     0x07C0, 0x1830, 0x2008, 0x47C4, 0x4FE4, 0x9FF2, 0x9FF2, 0x9FF2, 
  71.     0x9FF2, 0x9FF2, 0x4FE4, 0x47C4, 0x2008, 0x1830, 0x07C0, 0x0000, 
  72.     0x0000, 0x03C0, 0x0C30, 0x1008, 0x23C4, 0x27E4, 0x4FF2, 0x4FF2, 
  73.     0x4FF2, 0x4FF2, 0x27E4, 0x23C4, 0x1008, 0x0C30, 0x03C0, 0x0000, 
  74.     0x0000, 0x03C0, 0x0C30, 0x1188, 0x27E4, 0x2FF4, 0x4FF2, 0x5FFA, 
  75.     0x5FFA, 0x4FF2, 0x2FF4, 0x27E4, 0x1188, 0x0C30, 0x03C0, 0x0000, 
  76.     0x0000, 0x0000, 0x03C0, 0x0C30, 0x1008, 0x13C8, 0x27E4, 0x27E4, 
  77.     0x27E4, 0x27E4, 0x13C8, 0x1008, 0x0C30, 0x03C0, 0x0000, 0x0000, 
  78.     0x0000, 0x43C2, 0x2C34, 0x1008, 0x2814, 0x2424, 0x4242, 0x4182, 
  79.     0x4182, 0x4242, 0x2424, 0x2814, 0x1008, 0x2C34, 0x43C2, 0x0000, 
  80.     0x0000, 0x03C0, 0x0C30, 0x1008, 0x23C4, 0x2624, 0x4F92, 0x4FD2, 
  81.     0x4FF2, 0x4FF2, 0x27E4, 0x23C4, 0x1008, 0x0C30, 0x03C0, 0x0000, 
  82.     0x0000, 0x03C0, 0x0C30, 0x1008, 0x23C4, 0x27E4, 0x4FF2, 0x4FF2, 
  83.     0x4FF2, 0x4FF2, 0x27E4, 0x23C4, 0x1008, 0x0C30, 0x03C0, 0x0000
  84. };
  85.     
  86. static int radio_hi_off[] =
  87. {
  88.     0x0000, 0x03E0, 0x0C18, 0x1004, 0x2006, 0x2002, 0x4003, 0x4003, 
  89.     0x4003, 0x4003, 0x4003, 0x2006, 0x200E, 0x181C, 0x0FF8, 0x03E0,
  90.     0x07C0, 0x1830, 0x2008, 0x4004, 0x4004, 0x8002, 0x8002, 0x8002, 
  91.     0x8002, 0x8002, 0x4004, 0x4004, 0x2008, 0x1830, 0x07C0, 0x0000, 
  92.     0x0000, 0x03C0, 0x0C30, 0x1008, 0x2004, 0x2004, 0x4002, 0x4002, 
  93.     0x4002, 0x4002, 0x2004, 0x2004, 0x1008, 0x0C30, 0x03C0, 0x0000, 
  94.     0x0000, 0x0000, 0x03C0, 0x0C30, 0x1008, 0x1008, 0x2004, 0x2004, 
  95.     0x2004, 0x2004, 0x1008, 0x1008, 0x0C30, 0x03C0, 0x0000, 0x0000, 
  96.     0x0000, 0x03C0, 0x0C30, 0x1008, 0x23C4, 0x2424, 0x4812, 0x4812, 
  97.     0x4812, 0x4812, 0x2424, 0x23C4, 0x1008, 0x0C30, 0x03C0, 0x0000
  98. };
  99.  
  100. static int radio_lo_on[] =
  101. {
  102.     0x07C0, 0x3838, 0x638C, 0xCFE6, 0xCFE6, 0x638C, 0x3838, 0x07C0
  103. };
  104.  
  105. static int radio_lo_off[] =
  106. {
  107.     0x07C0, 0x3838, 0x600C, 0xC006, 0xC006, 0x600C, 0x3838, 0x07C0
  108. };
  109.  
  110. static int check_hi_on[] =
  111. {
  112.     0x0000, 0x7FFF, 0x4001, 0x580D, 0x5C1D, 0x4E39, 0x4771, 0x43E1, 
  113.     0x41C1, 0x43E1, 0x4771, 0x4E39, 0x5C1D, 0x580D, 0x4001, 0x7FFF, 
  114.     0x0000, 0x7FFE, 0x6006, 0x500A, 0x4812, 0x4422, 0x4242, 0x4182, 
  115.     0x4182, 0x4242, 0x4422, 0x4812, 0x500A, 0x6006, 0x7FFE, 0x0000, 
  116.     0x0000, 0x7FFE, 0x4002, 0x500A, 0x4812, 0x4422, 0x4242, 0x4182, 
  117.     0x4182, 0x4242, 0x4422, 0x4812, 0x500A, 0x4002, 0x7FFE, 0x0000, 
  118.     0x0000, 0x4002, 0x3FFC, 0x300C, 0x2814, 0x2424, 0x2244, 0x2184, 
  119.     0x2184, 0x2244, 0x2424, 0x2814, 0x300C, 0x3FFC, 0x4002, 0x0000
  120. };
  121.  
  122. static int check_hi_off[] =
  123. {
  124.     0x0000, 0x7FFF, 0x4001, 0x4001, 0x4001, 0x4001, 0x4001, 0x4001, 
  125.     0x4001, 0x4001, 0x4001, 0x4001, 0x4001, 0x4001, 0x4001, 0x7FFF, 
  126.     0x0000, 0x7FFE, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 
  127.     0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x7FFE, 0x0000, 
  128.     0x0000, 0x0000, 0x3FFC, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 
  129.     0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x3FFC, 0x0000, 0x0000
  130. };
  131.  
  132. static int check_lo_on[] = 
  133. {
  134.     0xFFFE, 0xB01A, 0x8C62, 0x8382, 0x8C62, 0xB01A, 0xFFFE, 0x0000
  135. };
  136.  
  137. static int check_lo_off[] = 
  138. {
  139.     0xFFFE, 0x8002, 0x8002, 0x8002, 0x8002, 0x8002, 0xFFFE, 0x0000
  140. };
  141.  
  142. static int cycle_sel[] =
  143. {
  144.     0x07E0, 0x5C1C, 0x7806, 0x7C00, 0x003E, 0x601E, 0x383A, 0x07E0
  145. };
  146.  
  147. static int down_arrow_sel[] =
  148. {
  149.     0xFFFE, 0x7FFC, 0x3FF8, 0x1FF0, 0x0FE0, 0x07C0, 0x0380, 0x0100
  150. };
  151.  
  152. static int down_arrow_unsel[] =
  153. {
  154.     0xFFFE, 0x4004, 0x2008, 0x1010, 0x0820, 0x0440, 0x0280, 0x0100
  155. };
  156.  
  157. static int left_arrow_sel[] =
  158. {
  159.     0x0000, 0x000F, 0x00FF, 0x0FFF, 0xFFFF, 0x0FFF, 0x00FF, 0x000F
  160. };
  161.  
  162. static int left_arrow_unsel[] =
  163. {
  164.     0x0000, 0x000F, 0x00F1, 0x0F01, 0xF001, 0x0F01, 0x00F1, 0x000F
  165. };
  166.  
  167. static int right_arrow_sel[] =
  168. {
  169.     0x0000, 0xF800, 0xFF80, 0xFFF8, 0xFFFF, 0xFFF8, 0xFF80, 0xF800
  170. };
  171.  
  172. static int right_arrow_unsel[] =
  173. {
  174.     0x0000, 0xF800, 0x8780, 0x8078, 0x8007, 0x8078, 0x8780, 0xF800
  175. };
  176.  
  177. static int up_arrow_sel[] =
  178. {
  179.     0x0100, 0x0380, 0x07C0, 0x0FE0, 0x1FF0, 0x3FF8, 0x7FFC, 0xFFFE
  180. };
  181.  
  182. static int up_arrow_unsel[] =
  183. {
  184.     0x0100, 0x0280, 0x0440, 0x0820, 0x1010, 0x2008, 0x4004, 0xFFFE
  185. };
  186.  
  187. static int dropdown_unsel[] =
  188. {
  189.     0x0000, 0x7FFE, 0x0000, 0x7FFE, 0x1FF8, 0x07E0, 0x0180, 0x0000
  190. };
  191.  
  192. static IMAGE radio_im[] =
  193. {
  194.     {radio_hi_on + 32, radio_hi_off + 32, radio_lo_on, radio_lo_off}, 
  195.     {radio_hi_on, radio_hi_off, NULL, NULL}, 
  196.     {radio_hi_on + 16, radio_hi_off + 16, NULL, NULL}, 
  197.     {radio_hi_on + 48, radio_hi_off + 32, NULL, NULL}, 
  198.     {radio_hi_on + 64, radio_hi_off + 48, NULL, NULL}, 
  199.     {radio_hi_on + 80, radio_hi_off + 32, NULL, NULL}, 
  200.     {radio_hi_on + 96, radio_hi_off + 64, NULL, NULL}, 
  201.     {radio_hi_on + 112, radio_hi_off + 64, NULL, NULL}
  202. };
  203.  
  204. static IMAGE check_im[] =
  205. {
  206.     {check_hi_on + 16, check_hi_off + 16, check_lo_on, check_lo_off}, 
  207.     {check_hi_on, check_hi_off, NULL, NULL}, 
  208.     {check_hi_on + 32, check_hi_off + 32, NULL, NULL}, 
  209.     {check_hi_on + 32, check_hi_off + 16, NULL, NULL}, 
  210.     {check_hi_on + 48, check_hi_off + 32, NULL, NULL}
  211. };
  212.  
  213. static IMAGE cycle_im[] =
  214. {
  215.     {NULL, NULL, cycle_sel, cycle_sel}
  216. };
  217.  
  218. static IMAGE down_im[] =
  219. {
  220.     {NULL, NULL, down_arrow_sel, down_arrow_unsel}
  221. };
  222.  
  223. static IMAGE up_im[] =
  224. {
  225.     {NULL, NULL, up_arrow_sel, up_arrow_unsel}
  226. };
  227.  
  228. static IMAGE left_im[] =
  229. {
  230.     {NULL, NULL, left_arrow_sel, left_arrow_unsel}
  231. };
  232.  
  233. static IMAGE right_im[] =
  234. {
  235.     {NULL, NULL, right_arrow_sel, right_arrow_unsel}
  236. };
  237.  
  238. static IMAGE dropdown_im[] =
  239. {
  240.     {NULL, NULL, dropdown_unsel, dropdown_unsel}
  241. };
  242.  
  243. IMAGES radios = {8, radio_im};
  244. IMAGES checks = {5, check_im};
  245. IMAGES cycles = {1, cycle_im};
  246. IMAGES uparrow = {1, up_im};
  247. IMAGES dnarrow = {1, down_im};
  248. IMAGES lfarrow = {1, left_im};
  249. IMAGES rtarrow = {1, right_im};
  250. IMAGES dropdown = {1, dropdown_im};
  251.  
  252. GLOBAL void Change3DType(int type)
  253. {
  254.     draw3dtype = type;
  255. }
  256.  
  257. GLOBAL void set_images(IMAGES *images, int **on, int **off)
  258. {
  259.     register IMAGE *im = images->image;
  260.     register int i;
  261.     int dummy;
  262.  
  263.     for (i = 0; i < images->count; i++) {
  264.         vdi_trans(16, 16, im->hi_on);
  265.         vdi_trans(16, 16, im->hi_off);
  266.  
  267.         if (big_img != TRUE) {
  268.             if (!im->lo_on || big_img == FAIL)
  269.                 scale_img(im->hi_on, 16, 16, DARK_SCALING, &dummy, &dummy);
  270.             else {
  271.                 im->hi_on = im->lo_on;
  272.                 vdi_trans(16, 8, im->hi_on);
  273.             }
  274.  
  275.             if (!im->lo_off || big_img < 0)
  276.                 scale_img(im->hi_off, 16, 16, DARK_SCALING, &dummy, &dummy);
  277.             else {
  278.                 im->hi_off = im->lo_off;
  279.                 vdi_trans(16, 8, im->hi_off);
  280.             }
  281.         }
  282.  
  283.         im++;
  284.     }
  285.  
  286.     if (images->count > 0) {
  287.         *on = images->image->hi_on;
  288.  
  289.         if (off)
  290.             *off = images->image->hi_off;
  291.     }
  292. }
  293.  
  294. /*
  295.  *    Blit image onto screen
  296.  */
  297. GLOBAL void vrt_copy(int *image, PARMBLK *pb, int color, int selected)
  298. {
  299.     register MFDB src;
  300.     register int pxy[8], col[2], off = (big_img < 0) ? 1 : 0;
  301.     register int attr[10];
  302.  
  303.     pxy[0] = pxy[1] = 0;
  304.     pxy[2] = image_w - 1;
  305.     pxy[3] = image_h - 1;
  306.     pxy[4] = pb->pb_x + (gr_cw - (image_w >> 1)) + off;
  307.     pxy[5] = pb->pb_y + ((gr_ch - image_h) >> 1) + off;
  308.     pxy[6] = pxy[4] + pxy[2];
  309.     pxy[7] = pxy[5] + pxy[3];
  310.  
  311.     if (selected) {
  312.         col[1] = color;
  313.         col[0] = 0;
  314.     } else {
  315.         col[0] = color;
  316.         col[1] = 0;
  317.     }
  318.  
  319.     init_mfdb(&src, image, 16, image_h, 0, 1);
  320.  
  321.     vqt_attributes(VDIhandle, attr);
  322.     vrt_cpyfm(VDIhandle, MD_REPLACE, pxy, &src, &screen, col);
  323.     vswr_mode(VDIhandle, attr[5]);
  324. }
  325.  
  326. /*
  327.  *    Output object
  328.  *
  329.  *    *pb = pointer to PARMBLK structure containing data
  330.  *
  331.  *    Returns: nothing
  332.  */
  333. LOCAL void pb_doobject(PARMBLK *pb, int xoff, int yoff)
  334. {
  335.     int dummy, effects = 0;
  336.     int interiorpxy[4], pa[6];
  337.     int extent[8], x, y;
  338.     EXTINFO *ex = (EXTINFO *) pb->pb_parm;
  339.     int oldtype = ex->oldtype & 0xff;
  340.     char *ptr, *string, *unformatted = ex->te_ptext;
  341.     int hotkey = -1, i = 0;
  342.     int flags = pb->pb_tree[pb->pb_obj].ob_flags;
  343.     int this_ch, this_bw;
  344.  
  345.     XVDI_SaveHandles();
  346.  
  347.     pa[0] = pb->pb_xc;
  348.     pa[1] = pb->pb_yc;
  349.     pa[2] = pb->pb_xc + pb->pb_wc - 1;
  350.     pa[3] = pb->pb_yc + pb->pb_hc - 1;
  351.     vs_clip(VDIhandle, 1, pa);
  352.  
  353.     if (ptr = string = strdup(unformatted)) {
  354.         while (*unformatted) {
  355.             if (*unformatted == '[')
  356.                 if (*(++unformatted))
  357.                     hotkey = i;
  358.                 else
  359.                     break;
  360.  
  361.             *(ptr++) = *(unformatted++);
  362.             i++;
  363.         }
  364.         *ptr = 0;
  365.  
  366.         if (xoff) pb->pb_x += xoff;
  367.         if (yoff) pb->pb_y += yoff;
  368.  
  369.         vst_height(VDIhandle, ex->te_font == 3 ? large_font : small_font, &dummy, &this_ch, &this_bw, &dummy);
  370.         vst_color(VDIhandle, ex->te_color.text_color);
  371.         vswr_mode(VDIhandle, MD_TRANS);
  372.  
  373.         if (pb->pb_currstate & 0x100) effects |= 1;
  374.         if (pb->pb_currstate & 0x200) effects |= 8;
  375.         if (pb->pb_currstate & 0x400) effects |= 4;
  376.         if (pb->pb_currstate & 0x800) effects |= 2;
  377.         if (pb->pb_currstate & 0x1000) effects |= 16;
  378.  
  379.         vst_effects(VDIhandle, effects);
  380.         vqt_extent(VDIhandle, string, extent);
  381.  
  382.         {
  383.              int add = draw3dtype == L_CUSTOM ? 1 : 0;
  384.  
  385.             interiorpxy[2] = (interiorpxy[0] = pb->pb_x + add) + pb->pb_w - (add * 2);
  386.             interiorpxy[3] = (interiorpxy[1] = pb->pb_y + add) + pb->pb_h - (add * 2);
  387.         }
  388.  
  389.         if (ex->te_thickness < 0) {
  390.             interiorpxy[0] -= ex->te_thickness;
  391.             interiorpxy[1] -= ex->te_thickness;
  392.             interiorpxy[2] += ex->te_thickness;
  393.             interiorpxy[3] += ex->te_thickness;
  394.         }
  395.  
  396.         if (ex->te_thickness > 0) {
  397.             interiorpxy[0] += ex->te_thickness;
  398.             interiorpxy[1] += ex->te_thickness;
  399.             interiorpxy[2] -= ex->te_thickness;
  400.             interiorpxy[3] -= ex->te_thickness;
  401.         }
  402.  
  403.         interiorpxy[2]--;
  404.         interiorpxy[3]--;
  405.  
  406.         switch (oldtype) {
  407.             default:
  408.                 if ((draw3dtype == L_CUSTOM || draw3dtype == L_MOTIF) && num_colors>4) {
  409.                     extent[0]++;
  410.                     extent[1]++;
  411.                 }
  412.  
  413.                 if (!((interiorpxy[2] - interiorpxy[0]) >= (extent[2] - extent[0]) &&
  414.                       (interiorpxy[3] - interiorpxy[1]) >= (extent[7] - extent[1])))
  415.                 break;
  416.  
  417.             case G_BOX:
  418.             case G_BOXTEXT:
  419.             case G_BOXCHAR:
  420.             case G_IBOX: {
  421.                     int pxyarray[16];
  422.  
  423.                     if (ex->te_thickness) {
  424.                         int count, maxima;
  425.  
  426.                         vsl_color(VDIhandle, ex->te_color.bord_color);
  427.  
  428.                         if (ex->te_thickness < 0)
  429.                             maxima = 1 - min(ex->te_thickness, 0);
  430.                         else
  431.                             maxima = max(ex->te_thickness, 0) + 1;
  432.  
  433.                         switch (draw3dtype) {
  434.                             case L_MULTITOS:
  435.                             case L_GENEVA:
  436.                             case L_STANDARD:
  437.                                 if ((flags & 0x600) != 0x400) {
  438.                                     for (count = 0; count < maxima; count++)
  439.                                         box(pb->pb_x + count, pb->pb_y + count, pb->pb_w - ((2 * count) + 1), pb->pb_h - ((2 * count) + 1), 1);
  440.                                     break;
  441.                                 }
  442.  
  443.                             case L_CUSTOM:
  444.                             case L_MOTIF: {
  445.                                     int i, col1, col2;
  446.  
  447.                                     if (pb->pb_currstate & SELECTED && flags & 0x0400)
  448.                                         col1 = 0, col2 = 9;
  449.                                     else
  450.                                         col1 = 9, col2 = 0;
  451.  
  452.                                     if (draw3dtype == L_CUSTOM || draw3dtype == L_MOTIF && draw3dtype != L_STANDARD) {
  453.                                         vsl_color(VDIhandle, col1);
  454.                                         for (i = 0; i < maxima; i++) {
  455.                                             pxyarray[0] = pb->pb_x + i;
  456.                                             pxyarray[1] = pxyarray[3] = pb->pb_y + pb->pb_h - (i + 1);
  457.                                             pxyarray[2] = pxyarray[4] = pb->pb_x + pb->pb_w - (i + 1);
  458.                                             pxyarray[5] = pb->pb_y + i;
  459.                                             v_pline(VDIhandle, 3, pxyarray);
  460.                                         }
  461.  
  462.                                         vsl_color(VDIhandle, col2);
  463.                                         for (i = 0; i < maxima; i++) {
  464.                                             pxyarray[0] = pxyarray[2] = pb->pb_x + i;
  465.                                             pxyarray[1] = pb->pb_y + pb->pb_h - (i + 1);
  466.                                             pxyarray[3] = pxyarray[5] = pb->pb_y + i;
  467.                                             pxyarray[4] = pb->pb_x + pb->pb_w - (i + 1);
  468.                                             v_pline(VDIhandle, 3, pxyarray);
  469.                                         }
  470.  
  471.                                         vsm_color(VDIhandle, (num_colors>4) ? 8 : 0);
  472.                                         for (i = 0; i < maxima; i++) {
  473.                                             pxyarray[0] = pb->pb_x + i;
  474.                                             pxyarray[1] = pb->pb_y + pb->pb_h - (i + 1);
  475.                                             pxyarray[2] = pb->pb_x + pb->pb_w - (i + 1);
  476.                                             pxyarray[3] = pb->pb_y + i;
  477.                                             v_pmarker(VDIhandle, 2, pxyarray);
  478.                                         }
  479.  
  480.                                         if (draw3dtype != L_MOTIF)
  481.                                             box(pb->pb_x, pb->pb_y, pb->pb_w - 1, pb->pb_h - 1, 1);
  482.                                     }
  483.                                 }
  484.                                 break;
  485.                         }
  486.                     }
  487.  
  488.                     if (oldtype != G_IBOX) {
  489.                         if (num_colors > 4 && flags & 0x600)
  490.                             vsf_color(VDIhandle, 8);
  491.                         else
  492.                             vsf_color(VDIhandle, 0);
  493.  
  494.                         if (draw3dtype==L_STANDARD)
  495.                             vsf_color(VDIhandle, 0);
  496.  
  497.                         vsf_interior(VDIhandle, FIS_SOLID);
  498.                         vr_recfl(VDIhandle, interiorpxy);
  499.                     }
  500.  
  501.                     if (ex->te_color.fill_ptn) {
  502.                         vsf_style(VDIhandle, ex->te_color.fill_ptn == 7 ? 8 : ex->te_color.fill_ptn);
  503.                         vsf_interior(VDIhandle, FIS_PATTERN);
  504.                         vsf_color(VDIhandle, ex->te_color.in_color);
  505.                         vr_recfl(VDIhandle, interiorpxy);
  506.                     }
  507.  
  508.                     if (flags & 0x200 && (draw3dtype == L_MULTITOS || draw3dtype == L_GENEVA)) {
  509.                         int col1, col2;
  510.  
  511.                         if (pb->pb_currstate & SELECTED && flags & 0x400)
  512.                             col1 = 1, col2 = ((draw3dtype==L_GENEVA) && num_colors>4) ? 8 : 0;
  513.                         else
  514.                             col1 = 0, col2 = 9;
  515.  
  516.                         vsl_color(VDIhandle, col1);
  517.                         pxyarray[0] = pxyarray[2] = interiorpxy[0];
  518.                         pxyarray[1] = (draw3dtype==L_GENEVA) ? interiorpxy[3] : interiorpxy[3] - 1;
  519.                         pxyarray[3] = pxyarray[5] = interiorpxy[1];
  520.                         pxyarray[4] = (draw3dtype==L_GENEVA) ? interiorpxy[2] : interiorpxy[2] - 1;
  521.                         v_pline(VDIhandle, 3, pxyarray);
  522.  
  523.                         vsl_color(VDIhandle, col2);
  524.                         pxyarray[0] = pxyarray[0] + 1;
  525.                         pxyarray[1] = pxyarray[3] = interiorpxy[3];
  526.                         pxyarray[2] = pxyarray[4] = interiorpxy[2];
  527.                         pxyarray[5] = interiorpxy[1] + 1;
  528.                         v_pline(VDIhandle, 3, pxyarray);
  529.  
  530.                         if (draw3dtype!=L_GENEVA) {
  531.                             vsm_color(VDIhandle, (num_colors>4) ? 8 : 0);
  532.                             pxyarray[0] = interiorpxy[0];
  533.                             pxyarray[1] = interiorpxy[3];
  534.                             pxyarray[2] = interiorpxy[2];
  535.                             pxyarray[3] = interiorpxy[1];
  536.                             v_pmarker(VDIhandle, 2, pxyarray);
  537.                         }
  538.                     }
  539.                 }
  540.  
  541.             case G_FTEXT:
  542.             case G_STRING:
  543.             case G_TEXT:
  544.                 if ((oldtype != G_BOX) &&
  545.                     (((ex->oldtype >> 8) != CUSTBTN) &&
  546.                     ((ex->oldtype >> 8) != CYCLEBTN)) &&
  547.                     ((ex->oldtype >> 8) != DROPDOWN)) {
  548.                     y = pb->pb_y + ((pb->pb_h - (extent[7] - extent[1])) / 2) + this_ch;
  549.                     x = pb->pb_x;
  550.  
  551.                     if (draw3dtype!=L_STANDARD) {
  552.                         if (pb->pb_currstate & SELECTED && flags & 0x400) {
  553.                             y++;
  554.                             x++;
  555.                         }
  556.                     }
  557.  
  558.                     switch (ex->te_just) {
  559.                         case 2:
  560.                             x += (pb->pb_w - (extent[2] - extent[0])) / 2;
  561.                             break;
  562.                         case 1:
  563.                             x += pb->pb_w - (extent[2] - extent[0]);
  564.                             break;
  565.                     }
  566.  
  567.                     if (pb->pb_currstate & 0x2000 && draw3dtype!=L_STANDARD) {
  568.                         vst_effects(VDIhandle, effects | 2);
  569.                         v_gtext(VDIhandle, x + 2, y + 2, string);
  570.                         vst_effects(VDIhandle, effects);
  571.                     }
  572.  
  573.                     if ((draw3dtype == L_CUSTOM || draw3dtype == L_MOTIF) && (num_colors > 4) && draw3dtype!=L_STANDARD) {
  574.                         vst_color(VDIhandle, 0);
  575.                         v_gtext(VDIhandle, x - 1, y - 1, string);
  576.                     }
  577.  
  578.                     vst_color(VDIhandle, ex->te_color.text_color);
  579.                     v_gtext(VDIhandle, x, y, string);
  580.  
  581.                     if (hotkey >= 0) {
  582.                         int pxyarray[4];
  583.  
  584.                         if ((draw3dtype == L_CUSTOM || draw3dtype == L_MOTIF) && (num_colors > 4)) {
  585.                             vsl_color(VDIhandle, 0);
  586.  
  587.                             if (hotkeylevel == HOTKEY_UNDERLINE) {
  588.                                 pxyarray[2] = ((pxyarray[0] = (x + this_bw * hotkey) - 1) + this_bw);
  589.                                 pxyarray[1] = (pxyarray[3] = (y + this_ch / 6) - 1);
  590.                                 v_pline(VDIhandle, 2, pxyarray);
  591.  
  592.                                 vst_color(VDIhandle, 0);
  593.                                 v_gtext(VDIhandle, x - 1, y - 1, string);
  594.                             }
  595.                         }
  596.  
  597.                         vsl_color(VDIhandle, ex->te_color.text_color);
  598.  
  599.                         if (hotkeylevel == HOTKEY_UNDERLINE) {
  600.                             pxyarray[2] = (pxyarray[0] = x + this_bw * hotkey) + this_bw;
  601.                             pxyarray[1] = pxyarray[3] = y + this_ch / 6;
  602.                             v_pline(VDIhandle, 2, pxyarray);
  603.  
  604.                             vst_color(VDIhandle, ex->te_color.text_color);
  605.                             v_gtext(VDIhandle, x, y, string);
  606.                         }
  607.                     }
  608.                 }
  609.                 break;
  610.         }
  611.  
  612.         if (pb->pb_currstate & SELECTED && (!(flags & 0x400) || (draw3dtype==L_STANDARD))) {
  613.             vsf_interior(VDIhandle, FIS_SOLID);
  614.             vsf_color(VDIhandle, 1);
  615.             vswr_mode(VDIhandle, MD_XOR);
  616.             vr_recfl(VDIhandle, interiorpxy);
  617.         }
  618.  
  619.         if (hotkey >= 0)
  620.             if (hotkeylevel == HOTKEY_INVERSE) {
  621.                 int pxyarray[4];
  622.  
  623.                 pxyarray[0] = (x + gr_cw * hotkey);
  624.                 pxyarray[1] = (y + this_ch / 6) - (this_ch + 2);
  625.                 pxyarray[2] = (x + gr_cw * hotkey) + (gr_cw - 1);
  626.                 pxyarray[3] = (y + this_ch / 6);
  627.  
  628.                 if (oldtype!=G_BOX || oldtype!=G_BOXTEXT || oldtype!=G_BUTTON) {
  629.                     vst_color(VDIhandle, 0);
  630.                     vswr_mode(VDIhandle, MD_TRANS);
  631.                     v_gtext(VDIhandle, x - 1, y - 1, string);
  632.  
  633.                     vsf_interior(VDIhandle, FIS_SOLID);
  634.                     vsf_color(VDIhandle, 0);
  635.                     vswr_mode(VDIhandle, MD_REPLACE);
  636.                     vr_recfl(VDIhandle, pxyarray);
  637.  
  638.                     vst_color(VDIhandle, ex->te_color.text_color);
  639.                     vswr_mode(VDIhandle, MD_TRANS);
  640.                     v_gtext(VDIhandle, x, y, string);
  641.  
  642.                     vsf_interior(VDIhandle, FIS_SOLID);
  643.                     vsf_color(VDIhandle, 1);
  644.                     vswr_mode(VDIhandle, MD_XOR);
  645.                     vr_recfl(VDIhandle, pxyarray);
  646.                 } else {
  647.                     vsf_interior(VDIhandle, FIS_SOLID);
  648.                     vsf_color(VDIhandle, 1);
  649.                     vswr_mode(VDIhandle, MD_REPLACE);
  650.                     vr_recfl(VDIhandle, pxyarray);
  651.  
  652.                     vst_color(VDIhandle, 0);
  653.                     vswr_mode(VDIhandle, MD_TRANS);
  654.                     v_gtext(VDIhandle, x, y, string);
  655.  
  656.                     vswr_mode(VDIhandle, MD_XOR);
  657.                     vst_color(VDIhandle, ex->te_color.text_color);
  658.                     v_gtext(VDIhandle, x, y, string);
  659.                 }
  660.             }
  661.  
  662.         if (pb->pb_currstate & DISABLED) {
  663.             vsf_interior(VDIhandle, FIS_PATTERN);
  664.  
  665.             interiorpxy[0] = pb->pb_x;
  666.             interiorpxy[1] = pb->pb_y;
  667.             interiorpxy[2] = pb->pb_x + pb->pb_w - 1;
  668.             interiorpxy[3] = pb->pb_y + pb->pb_h - 1;
  669.  
  670.             if (num_planes >= 4)
  671.                 vsf_color(VDIhandle, 8);
  672.             else
  673.                 vsf_color(VDIhandle, 0);
  674.  
  675.             vsf_style(VDIhandle, 4);
  676.             vswr_mode(VDIhandle, MD_TRANS);
  677.             vr_recfl(VDIhandle, interiorpxy);
  678.         }
  679.  
  680.         if (xoff) pb->pb_x -= xoff;
  681.         if (yoff) pb->pb_y -= yoff;
  682.  
  683.         free(string);
  684.     }
  685.  
  686.     XVDI_RestoreHandles();
  687. }
  688.  
  689. /*
  690.  *    Userdefined text proc
  691.  */
  692. LOCAL int cdecl draw_specialtext(PARMBLK *pb)
  693. {
  694.     int pxyarray[4];
  695.  
  696.     pb_doobject(pb, 0, 0);
  697.  
  698.     return pb->pb_currstate & ~(SELECTED | OUTLINED);
  699. }
  700.  
  701. /*
  702.  *    Userdefined underline proc
  703.  */
  704. LOCAL int cdecl draw_underline(PARMBLK *pb)
  705. {
  706.     int pxyarray[4];
  707.  
  708.     pb_doobject(pb, 0, 0);
  709.  
  710.     XVDI_SaveHandles();
  711.  
  712.     pxyarray[0] = pb->pb_xc;
  713.     pxyarray[1] = pb->pb_yc;
  714.     pxyarray[2] = pb->pb_xc + pb->pb_wc - 1;
  715.     pxyarray[3] = pb->pb_yc + pb->pb_hc - 1;
  716.     vs_clip(VDIhandle, 1, pxyarray);
  717.  
  718.     if (pb->pb_tree[pb->pb_obj].ob_state & DISABLED) {
  719.         vsl_type(VDIhandle, 7);
  720.         vsl_udsty(VDIhandle, 0x5555);
  721.     }
  722.  
  723.     vsl_color(VDIhandle, ((EXTINFO *) pb->pb_parm)->te_color.bord_color);
  724.  
  725.     pxyarray[0] = pb->pb_x;
  726.     pxyarray[2] = pb->pb_x + pb->pb_w;
  727.     pxyarray[1] = pxyarray[3] = pb->pb_y + pb->pb_h;
  728.     v_pline(VDIhandle, 2, pxyarray);
  729.  
  730.     XVDI_RestoreHandles();
  731.  
  732.     return FALSE;
  733. }
  734.  
  735. /*
  736.  *    Userdefined boxframe procedure
  737.  */
  738. LOCAL int cdecl draw_boxframe(PARMBLK *pb)
  739. {
  740.     int pxyarray[10], dummy;
  741.     EXTINFO *ex = (EXTINFO *) pb->pb_parm;
  742.     char *unformatted = ex->te_ptext;
  743.     int state = pb->pb_tree[pb->pb_obj].ob_state;
  744.     int disabled = pb->pb_tree[pb->pb_obj].ob_state & DISABLED;
  745.     int this_ch, this_bw;
  746.  
  747.     XVDI_SaveHandles();
  748.  
  749.     pxyarray[0] = pb->pb_xc;
  750.     pxyarray[1] = pb->pb_yc;
  751.     pxyarray[2] = pb->pb_xc + pb->pb_wc - 1;
  752.     pxyarray[3] = pb->pb_yc + pb->pb_hc - 1;
  753.     vs_clip(VDIhandle, 1, pxyarray);
  754.  
  755.     vswr_mode(VDIhandle, MD_REPLACE);
  756.     vsl_color(VDIhandle, ((EXTINFO *) pb->pb_parm)->te_color.bord_color);
  757.  
  758.     if ((num_colors<=4) || !(state & DRAW3D) || (draw3dtype == L_STANDARD))
  759.         box(pb->pb_x, pb->pb_y, pb->pb_w - 1, pb->pb_h - 1, ((EXTINFO *) pb->pb_parm)->te_color.bord_color);
  760.  
  761.     if ((state & DRAW3D) && (num_colors > 4) && (draw3dtype!=L_STANDARD)) {
  762.         vsl_color(VDIhandle, 9);
  763.         pxyarray[0] = pb->pb_x + pb->pb_w - 1;
  764.         pxyarray[1] = pxyarray[3] = pb->pb_y;
  765.         pxyarray[2] = pxyarray[4] = pb->pb_x;
  766.         pxyarray[5] = pb->pb_y + pb->pb_h - 1;
  767.         v_pline(VDIhandle, 3, pxyarray);
  768.  
  769.         vsl_color(VDIhandle, 0);
  770.         pxyarray[0] = pxyarray[2] = pb->pb_x + pb->pb_w - 1;
  771.         pxyarray[1] = pb->pb_y + 1;
  772.         pxyarray[3] = pxyarray[5] = pb->pb_y + pb->pb_h - 1;
  773.         pxyarray[4] = pb->pb_x + 1;
  774.         v_pline(VDIhandle, 3, pxyarray);
  775.  
  776.         vsf_interior(VDIhandle, FIS_SOLID);
  777.  
  778.         if (state & WHITEBACK)
  779.             vsf_color(VDIhandle, WHITE);
  780.         else
  781.             vsf_color(VDIhandle, 8);
  782.  
  783.         pxyarray[0] = pb->pb_x + 1;
  784.         pxyarray[1] = pb->pb_y + 1;
  785.         pxyarray[2] = pb->pb_x + pb->pb_w - 3;
  786.         pxyarray[3] = pb->pb_y + pb->pb_h - 3;
  787.         vr_recfl(VDIhandle, pxyarray);
  788.  
  789.         box(pb->pb_x + 1, pb->pb_y + 1, pb->pb_w - 3, pb->pb_h - 3, (state & WHITEBACK) ? 8 : WHITE);
  790.  
  791.         if (!(state & WHITEBACK)) {
  792.             vsl_color(VDIhandle, 9);
  793.  
  794.             pxyarray[0] = pxyarray[2] = pb->pb_x + pb->pb_w - 2;
  795.             pxyarray[1] = pb->pb_y + 2;
  796.             pxyarray[3] = pxyarray[5] = pb->pb_y + pb->pb_h - 2;
  797.             pxyarray[4] = pb->pb_x + 2;
  798.  
  799.             v_pline(VDIhandle, 3, pxyarray);
  800.         }
  801.     }
  802.  
  803.     vst_height(VDIhandle, ex->te_font == 3 ? large_font : small_font, &dummy, &this_ch, &this_bw, &dummy);
  804.     v_gtext(VDIhandle, pb->pb_x + gr_cw, pb->pb_y + (this_ch / 2), unformatted);
  805.  
  806.     if (pb->pb_tree[pb->pb_obj].ob_flags & BOXFRAMETITLE) {
  807.         vsl_color(VDIhandle, 9);
  808.         pxyarray[0] = pxyarray[2] = pb->pb_x + gr_cw;
  809.         pxyarray[1] = pxyarray[7] = pb->pb_y;
  810.         pxyarray[3] = pxyarray[5] = pb->pb_y - (gr_ch / 2);
  811.         pxyarray[4] = pxyarray[6] = pb->pb_x + (int)((strlen(unformatted) + 1) * gr_cw);
  812.         v_pline(VDIhandle, 4, pxyarray);
  813.  
  814.         vsl_color(VDIhandle, 8);
  815.         pxyarray[0] = pxyarray[2] = pb->pb_x + gr_cw;
  816.         pxyarray[1] = pxyarray[7] = pb->pb_y + 1;
  817.         pxyarray[3] = pxyarray[5] = pb->pb_y + (gr_ch / 2) + 1;
  818.         pxyarray[4] = pxyarray[6] = pb->pb_x + (int)((strlen(unformatted) + 1) * gr_cw);
  819.         v_pline(VDIhandle, 4, pxyarray);
  820.     }
  821.  
  822.     XVDI_RestoreHandles();
  823.  
  824.     return pb->pb_currstate | disabled;
  825. }
  826.  
  827. /*
  828.  *    Userdefined buttons
  829.  */
  830. LOCAL int cdecl draw_custbutton(PARMBLK *pb)
  831. {
  832.     static int IMask0Mon[] = {0x07C0,0x1FF0,0x3FF8,0x7FFC,0x7FFC,0xFFFE,0xFFFE,0xFFFE,
  833.                                0xFFFE,0xFFFE,0x7FFC,0x7FFC,0x3FF8,0x1FF0,0x07C0,0x0000};
  834.     static int IData0Mon[] = {0x07C0,0x1830,0x2008,0x4004,0x4004,0x8002,0x8002,0x8002,
  835.                                0x8002,0x8002,0x4004,0x4004,0x2008,0x1830,0x07C0,0x0000};
  836.     static int SMask0Mon[] = {0x07C0,0x1FF0,0x3FF8,0x7FFC,0x7FFC,0xFFFE,0xFFFE,0xFFFE,
  837.                                0xFFFE,0xFFFE,0x7FFC,0x7FFC,0x3FF8,0x1FF0,0x07C0,0x0000};
  838.     static int SData0Mon[] = {0x07C0,0x1830,0x2008,0x4384,0x47C4,0x8FE2,0x9FF2,0x9FF2,
  839.                                0x9FF2,0x8FE2,0x47C4,0x4384,0x2008,0x1830,0x07C0,0x0000};
  840.     static int IMask0Col[] = {0x07C0,0x1FF0,0x3FF8,0x7FFC,0x7FFC,0xFFFE,0xFFFE,0xFFFE,
  841.                                0xFFFE,0xFFFE,0x7FFC,0x7FFC,0x3FF8,0x1FF0,0x07C0,0x0000};
  842.     static int IData0Col[] = {0x07C0,0x1830,0x2388,0x4FE4,0x5FF4,0x9FF2,0xBFFA,0xBFFA,
  843.                                0xBFFA,0x9FF2,0x5FF4,0x4FE4,0x2388,0x1830,0x07C0,0x0000,
  844.                                0x07C0,0x1830,0x2388,0x4FE4,0x5FF4,0x9FF2,0xBFFA,0xBFFA,
  845.                                0xBFFA,0x9FF2,0x5FF4,0x4FE4,0x2388,0x1830,0x07C0,0x0000,
  846.                                0x07C0,0x1830,0x2388,0x4FE4,0x5FF4,0x9FF2,0xBFFA,0xBFFA,
  847.                                0xBFFA,0x9FF2,0x5FF4,0x4FE4,0x2388,0x1830,0x07C0,0x0000,
  848.                                0x07C0,0x1830,0x2018,0x401C,0x400C,0x800E,0x8006,0x8006,
  849.                                0x8006,0x800E,0x400C,0x401C,0x2C78,0x1FF0,0x07C0,0x0000};
  850.     static int SMask0Col[] = {0x07C0,0x1FF0,0x3FF8,0x7FFC,0x7FFC,0xFFFE,0xFFFE,0xFFFE,
  851.                                0xFFFE,0xFFFE,0x7FFC,0x7FFC,0x3FF8,0x1FF0,0x07C0,0x0000};
  852.     static int SData0Col[] = {0x07C0,0x1FF0,0x3FE8,0x7FE4,0x7FF4,0xFFF2,0xFFFA,0xFFFA,
  853.                                0xFFFA,0xFFF2,0x7FF4,0x7FE4,0x3388,0x1830,0x07C0,0x0000,
  854.                                0x07C0,0x1FF0,0x3FE8,0x7FE4,0x7C74,0xF832,0xF01A,0xF01A,
  855.                                0xF01A,0xF832,0x7C74,0x7FE4,0x3388,0x1830,0x07C0,0x0000,
  856.                                0x07C0,0x1FF0,0x3FE8,0x7FE4,0x7C74,0xF832,0xF01A,0xF01A,
  857.                                0xF01A,0xF832,0x7C74,0x7FE4,0x3388,0x1830,0x07C0,0x0000,
  858.                                0x07C0,0x1FF0,0x3C68,0x7004,0x6004,0xE002,0xC002,0xC002,
  859.                                0xC002,0xE002,0x6004,0x7004,0x3008,0x1830,0x07C0,0x0000};
  860.     static int IMask1Mon[] = {0x0FE0,0x7FFC,0xFFFE,0xFFFE,0xFFFE,0x7FFC,0x0FE0,0x0000};
  861.     static int IData1Mon[] = {0x0FE0,0x701C,0x8002,0x8002,0x8002,0x701C,0x0FE0,0x0000};
  862.     static int SMask1Mon[] = {0x0FE0,0x7FFC,0xFFFE,0xFFFE,0xFFFE,0x7FFC,0x0FE0,0x0000};
  863.     static int SData1Mon[] = {0x0FE0,0x701C,0x87C2,0x9FF2,0x87C2,0x701C,0x0FE0,0x0000};
  864.     static int IMask1Col[] = {0x0FE0,0x7FFC,0xFFFE,0xFFFE,0xFFFE,0x7FFC,0x0FE0,0x0000};
  865.     static int IData1Col[] = {0x0FE0,0x701C,0x87C2,0xBFFA,0x87C2,0x701C,0x0FE0,0x0000,
  866.                                0x0FE0,0x701C,0x87C2,0xBFFA,0x87C2,0x701C,0x0FE0,0x0000,
  867.                                0x0FE0,0x701C,0x87C2,0xBFFA,0x87C2,0x701C,0x0FE0,0x0000,
  868.                                0x0FE0,0x701C,0x8006,0x8006,0xB83E,0x7FFC,0x0FE0,0x0000};
  869.     static int SMask1Col[] = {0x0FE0,0x7FFC,0xFFFE,0xFFFE,0xFFFE,0x7FFC,0x0FE0,0x0000};
  870.     static int SData1Col[] = {0x0FE0,0x7FFC,0xFFFA,0xFFFA,0xC7C2,0x701C,0x0FE0,0x0000,
  871.                                0x0FE0,0x7FFC,0xFC7A,0xF01A,0xC442,0x701C,0x0FE0,0x0000,
  872.                                0x0FE0,0x7FFC,0xFC7A,0xF01A,0xC442,0x701C,0x0FE0,0x0000,
  873.                                0x0FE0,0x7FFC,0xF83A,0xC002,0xC002,0x701C,0x0FE0,0x0000};
  874.     static int IMask2Mon[] = {0x3800,0x7C00,0xFE00,0xFE00,0xFE00,0x7C00,0x3800,0x0000};
  875.     static int IData2Mon[] = {0x3800,0x4400,0x8200,0x8200,0x8200,0x4400,0x3800,0x0000};
  876.     static int SMask2Mon[] = {0x3800,0x7C00,0xFE00,0xFE00,0xFE00,0x7C00,0x3800,0x0000};
  877.     static int SData2Mon[] = {0x3800,0x4400,0xBA00,0xBA00,0xBA00,0x4400,0x3800,0x0000};
  878.     static int IMask2Col[] = {0x3800,0x7C00,0xFE00,0xFE00,0xFE00,0x7C00,0x3800,0x0000};
  879.     static int IData2Col[] = {0x3800,0x4400,0xBA00,0xBA00,0xBA00,0x4400,0x3800,0x0000,
  880.                                0x3800,0x4400,0xBA00,0xBA00,0xBA00,0x4400,0x3800,0x0000,
  881.                                0x3800,0x4400,0xBA00,0xBA00,0xBA00,0x4400,0x3800,0x0000,
  882.                                0x3800,0x4400,0x8600,0x8600,0x8600,0x7C00,0x3800,0x0000};
  883.     static int SMask2Col[] = {0x3800,0x7C00,0xFE00,0xFE00,0xFE00,0x7C00,0x3800,0x0000};
  884.     static int SData2Col[] = {0x3800,0x7C00,0xFA00,0xFA00,0xFA00,0x4400,0x3800,0x0000,
  885.                                0x3800,0x7C00,0xC200,0xC200,0xC200,0x4400,0x3800,0x0000,
  886.                                0x3800,0x7C00,0xC200,0xC200,0xC200,0x4400,0x3800,0x0000,
  887.                                0x3800,0x7C00,0xC200,0xC200,0xC200,0x4400,0x3800,0x0000};
  888.     static int *bufIMask = NULL,*bufIData = NULL;
  889.     static int *bufSMask = NULL,*bufSData = NULL;
  890.     static int width = 0,height = 0,planes = 0;
  891.     static int col[2] = {WHITE,WHITE};
  892.     int    vdiHandle,pxy[8];
  893.     MFDB mfdb;
  894.     int pxyarray[8];
  895.     int disabled = pb->pb_tree[pb->pb_obj].ob_state & DISABLED;
  896.     EXTINFO *ex = (EXTINFO *) pb->pb_parm;
  897.     int obtype = ex->oldtype;
  898.     char *unformatted = ex->te_ptext;
  899.     int newx, newy;
  900.  
  901.     if (((obtype >> 8) == CUSTOM) && (pb->pb_tree[pb->pb_obj].ob_flags & RBUTTON)) {
  902.         if (bufIMask == NULL) {
  903.             ICONBLK    iconBlk;
  904.  
  905.             if ((bufIMask = malloc(32 * 2 * ((planes = (num_planes < 4 ? 1 : num_planes)) + 1))) != NULL) {
  906.                 bufSData = (bufSMask = (bufIData = bufIMask + 16) + 16 * planes) + 16;
  907.                 if (gr_ch == 16) {
  908.                     width  = iconBlk.ib_wicon =
  909.                     height = iconBlk.ib_hicon = 16;
  910.  
  911.                     if (planes >= 4) {
  912.                         FixColIcon(&iconBlk,planes,IData0Col,IMask0Col,
  913.                                    bufIData,bufIMask,NULL,NULL,NULL);
  914.                         FixColIcon(&iconBlk,planes,SData0Col,SMask0Col,
  915.                                    bufSData,bufSMask,NULL,NULL,NULL);
  916.                     } else {
  917.                         FixColIcon(&iconBlk,planes,IData0Mon,IMask0Mon,
  918.                                    bufIData,bufIMask,NULL,NULL,NULL);
  919.                         FixColIcon(&iconBlk,planes,SData0Mon,SMask0Mon,
  920.                                    bufSData,bufSMask,NULL,NULL,NULL);
  921.                     }
  922.                 } else {
  923.                     int        workout[57];
  924.  
  925.                     vq_extnd(VDIhandle,0,workout);
  926.                     if ((int)(((long)workout[3] * 100L) / (long)workout[4]) < 75) {
  927.                         width  = iconBlk.ib_wicon = 16;
  928.                         height = iconBlk.ib_hicon = 8;
  929.  
  930.                         if (planes >= 4) {
  931.                             FixColIcon(&iconBlk,planes,IData1Col,IMask1Col,
  932.                                        bufIData,bufIMask,NULL,NULL,NULL);
  933.                             FixColIcon(&iconBlk,planes,SData1Col,SMask1Col,
  934.                                        bufSData,bufSMask,NULL,NULL,NULL);
  935.                         } else {
  936.                             FixColIcon(&iconBlk,planes,IData1Mon,IMask1Mon,
  937.                                        bufIData,bufIMask,NULL,NULL,NULL);
  938.                             FixColIcon(&iconBlk,planes,SData1Mon,SMask1Mon,
  939.                                        bufSData,bufSMask,NULL,NULL,NULL);
  940.                         }
  941.                     } else {
  942.                         width  = iconBlk.ib_wicon =
  943.                         height = iconBlk.ib_hicon = 8;
  944.                         if (planes >= 4) {
  945.                             FixColIcon(&iconBlk,planes,IData2Col,IMask2Col,
  946.                                        bufIData,bufIMask,NULL,NULL,NULL);
  947.                             FixColIcon(&iconBlk,planes,SData2Col,SMask2Col,
  948.                                        bufSData,bufSMask,NULL,NULL,NULL);
  949.                         } else {
  950.                             FixColIcon(&iconBlk,planes,IData2Mon,IMask2Mon,
  951.                                        bufIData,bufIMask,NULL,NULL,NULL);
  952.                             FixColIcon(&iconBlk,planes,SData2Mon,SMask2Mon,
  953.                                        bufSData,bufSMask,NULL,NULL,NULL);
  954.                         }
  955.                     }
  956.                 }
  957.             }
  958.         }
  959.     }
  960.  
  961.     newx = (pb->pb_x + (pb->pb_w / 2));
  962.     newy = (pb->pb_y + (pb->pb_h / 2));
  963.  
  964.     newx -= (image_w / 2);
  965.     newy -= (image_h / 2);
  966.  
  967.     switch (obtype >> 8) {
  968.         case CUSTOM:
  969.             if (pb->pb_tree[pb->pb_obj].ob_flags & RBUTTON) {
  970.                 pxy[0] = pxy[1] = 0;
  971.                 pxy[6] = (pxy[4] = pb->pb_x + 16 - width) + (pxy[2] = width  - 1);
  972.                 pxy[7] = (pxy[5] = pb->pb_y             ) + (pxy[3] = height - 1);
  973.                 mfdb.fd_addr    = pb->pb_currstate & SELECTED ?
  974.                                   bufSMask : bufIMask;
  975.                 mfdb.fd_w        = width;
  976.                 mfdb.fd_h        = height;
  977.                 mfdb.fd_wdwidth    = 1;
  978.                 mfdb.fd_stand    = 1;
  979.                 mfdb.fd_nplanes    = 1;
  980.                 mfdb.fd_r1        =
  981.                 mfdb.fd_r2        =
  982.                 mfdb.fd_r3        = 0;
  983.  
  984.                 vrt_cpyfm(VDIhandle,MD_TRANS,pxy,&mfdb,&screen,col);
  985.  
  986.                 mfdb.fd_addr    = pb->pb_currstate & SELECTED ?
  987.                                   bufSData : bufIData;
  988.                 mfdb.fd_nplanes    = planes;
  989.             }
  990.  
  991.             if (pb->pb_tree[pb->pb_obj].ob_flags & RBUTTON) {
  992.                 if (planes > 1) {
  993.                     mfdb.fd_stand    = 0;
  994.                     vro_cpyfm(VDIhandle,num_planes > 8 ? S_AND_D : S_OR_D,
  995.                               pxy,&mfdb,&screen);
  996.                 } else {
  997.                     if ((pb->pb_currstate & SELECTED) && !disabled)
  998.                         vrt_copy(radio_on, pb, 1, 0);
  999.                     else
  1000.                         vrt_copy(radio_off, pb, 1, 0);
  1001.                 }
  1002.             } else
  1003.                 if ((pb->pb_currstate & SELECTED) && !disabled)
  1004.                     vrt_copy(box_on, pb, 1, 0);
  1005.                 else
  1006.                     vrt_copy(box_off, pb, 1, 0);
  1007.  
  1008.             vsl_color(VDIhandle, 1);
  1009.             pb->pb_currstate &= ~SELECTED;
  1010.  
  1011. /*            pb_doobject(pb, 3 * gr_cw, 0); */
  1012.             pb_doobject(pb, 0, 0);
  1013.             break;
  1014.  
  1015.         case CYCLEBTN:
  1016.             pb_doobject(pb, 0, 0);
  1017.  
  1018.             pb->pb_x = newx;
  1019.             pb->pb_y = newy;
  1020.  
  1021.             if (pb->pb_currstate & SELECTED)
  1022.                 vrt_copy(cycle_on, pb, 1, 0);
  1023.             else
  1024.                 vrt_copy(cycle_off, pb, 1, 0);
  1025.  
  1026.             pb->pb_currstate &= ~SELECTED;
  1027.             break;
  1028.  
  1029.         case DROPDOWN:
  1030.             pb_doobject(pb, 0, 0);
  1031.  
  1032.             pb->pb_x = newx;
  1033.             pb->pb_y = newy;
  1034.  
  1035.             if (pb->pb_currstate & SELECTED)
  1036.                 vrt_copy(dropdown_on, pb, 1, 0);
  1037.             else
  1038.                 vrt_copy(dropdown_off, pb, 1, 0);
  1039.  
  1040.             pb->pb_currstate &= ~SELECTED;
  1041.             break;
  1042.  
  1043.         case CUSTBTN:
  1044.             switch(*unformatted) {
  1045.                 case '\001':
  1046.                     pb_doobject(pb, 0, 0);
  1047.  
  1048.                     pb->pb_x = newx;
  1049.                     pb->pb_y = newy;
  1050.  
  1051.                     if (pb->pb_currstate & SELECTED)
  1052.                         vrt_copy(up_on, pb, 1, 0);
  1053.                     else
  1054.                         vrt_copy(up_off, pb, 1, 0);
  1055.  
  1056.                     pb->pb_currstate &= ~SELECTED;
  1057.                     break;
  1058.  
  1059.                 case '\002':
  1060.                     pb_doobject(pb, 0, 0);
  1061.  
  1062.                     pb->pb_x = newx;
  1063.                     pb->pb_y = newy;
  1064.  
  1065.                     if (pb->pb_currstate & SELECTED)
  1066.                         vrt_copy(down_on, pb, 1, 0);
  1067.                     else
  1068.                         vrt_copy(down_off, pb, 1, 0);
  1069.  
  1070.                     pb->pb_currstate &= ~SELECTED;
  1071.                     break;
  1072.  
  1073.                 case '\003':
  1074.                     pb_doobject(pb, 0, 0);
  1075.  
  1076.                     pb->pb_x = newx;
  1077.                     pb->pb_y = newy;
  1078.  
  1079.                     if (pb->pb_currstate & SELECTED)
  1080.                         vrt_copy(right_on, pb, 1, 0);
  1081.                     else
  1082.                         vrt_copy(right_off, pb, 1, 0);
  1083.  
  1084.                     pb->pb_currstate &= ~SELECTED;
  1085.                     break;
  1086.  
  1087.                 case '\004':
  1088.                     pb_doobject(pb, 0, 0);
  1089.  
  1090.                     pb->pb_x = newx;
  1091.                     pb->pb_y = newy;
  1092.  
  1093.                     if (pb->pb_currstate & SELECTED)
  1094.                         vrt_copy(left_on, pb, 1, 0);
  1095.                     else
  1096.                         vrt_copy(left_off, pb, 1, 0);
  1097.  
  1098.                     pb->pb_currstate &= ~SELECTED;
  1099.                     break;
  1100.             }
  1101.             break;
  1102.     }
  1103.  
  1104. /*    return pb->pb_currstate | disabled; */
  1105.     return(pb->pb_currstate & ~(SELECTED|SHADOWED|(num_planes < 4 ? 0 : DISABLED)));
  1106. }
  1107.  
  1108. /*
  1109.  *    Userdefined menuline function
  1110.  */
  1111. LOCAL int cdecl draw_menuline(PARMBLK *pb)
  1112. {
  1113.     int attr[10], fillattr[5], lineattr[6], pxyarray[6];
  1114.     GRECT line1, line2;
  1115.  
  1116.     vqt_attributes(VDIhandle, attr);
  1117.     vqf_attributes(VDIhandle, fillattr);
  1118.     vql_attributes(VDIhandle, lineattr);
  1119.  
  1120.     pxyarray[0] = pb->pb_xc;
  1121.     pxyarray[1] = pb->pb_yc;
  1122.     pxyarray[2] = pb->pb_xc + pb->pb_wc - 1;
  1123.     pxyarray[3] = pb->pb_yc + pb->pb_hc - 1;
  1124.     vs_clip(VDIhandle, 1, pxyarray);
  1125.  
  1126.     line1.g_x = line2.g_x = pb->pb_x;
  1127.     line1.g_y = line1.g_h = pb->pb_y + (pb->pb_h / 2) - 1;
  1128.     line1.g_w = line2.g_w = pb->pb_x + pb->pb_w - 1;
  1129.     line2.g_y = line2.g_h = pb->pb_y + (pb->pb_h / 2);
  1130.  
  1131.     vsl_color(VDIhandle, ((EXTINFO *) pb->pb_parm)->te_color.bord_color);
  1132.  
  1133.     if (pb->pb_tree[pb->pb_obj].ob_state & DISABLED) {
  1134.         vsl_type(VDIhandle, 7);
  1135.         vsl_udsty(VDIhandle, 0xAAAA);
  1136.         line(line1.g_x, line1.g_y, line1.g_w, line1.g_h);
  1137.  
  1138.         vsl_udsty(VDIhandle, 0x5555);
  1139.         line(line2.g_x, line2.g_y, line2.g_w, line2.g_h);
  1140.     } else {
  1141.         line(line1.g_x, line1.g_y, line1.g_w, line1.g_h);
  1142.         line(line2.g_x, line2.g_y, line2.g_w, line2.g_h);
  1143.     }
  1144.  
  1145.     vst_color(VDIhandle, attr[1]);
  1146.     vswr_mode(VDIhandle, attr[5]);
  1147.  
  1148.     vsf_color(VDIhandle, fillattr[1]);
  1149.     vsf_interior(VDIhandle, fillattr[0]);
  1150.     vsf_style(VDIhandle, fillattr[2]);
  1151.  
  1152.     vsl_color(VDIhandle, lineattr[1]);
  1153.     vsl_type(VDIhandle, 7);
  1154.     vsl_udsty(VDIhandle, 0xFFFF);
  1155.  
  1156.     return FALSE;
  1157. }
  1158.  
  1159. /*
  1160.  *    Userdefined menu effects
  1161.  */
  1162. LOCAL int cdecl draw_menueffects(PARMBLK *pb)
  1163. {
  1164.     int attr[10], fillattr[5], lineattr[6], effects = 0, pxyarray[6];
  1165.     EXTINFO *ex = (EXTINFO *) pb->pb_parm;
  1166.     int pxy[8];
  1167.  
  1168.     if (pb->pb_currstate & 0x100) effects |= 1;
  1169.     if (pb->pb_currstate & 0x200) effects |= 8;
  1170.     if (pb->pb_currstate & 0x400) effects |= 4;
  1171.     if (pb->pb_currstate & 0x800) effects |= 2;
  1172.     if (pb->pb_currstate & 0x1000) effects |= 16;
  1173.  
  1174.     vst_effects(VDIhandle, effects);
  1175.     v_gtext(VDIhandle, pb->pb_x, pb->pb_y, ex->te_ptext);
  1176.  
  1177.     if (pb->pb_currstate & SELECTED) {
  1178.         vswr_mode(VDIhandle, MD_XOR);
  1179.         pxy[0] = pb->pb_x;
  1180.         pxy[1] = pb->pb_y;
  1181.         pxy[2] = pb->pb_x + pb->pb_w - 1;
  1182.         pxy[3] = pb->pb_y + pb->pb_h - 1;
  1183.  
  1184.         vsf_color(VDIhandle, BLACK);
  1185.         vr_recfl(VDIhandle, pxy);
  1186.     }
  1187.     return FALSE;
  1188. }
  1189.  
  1190. LOCAL int cdecl DrawColIcon(PARMBLK *parmBlk)
  1191. {
  1192.     static int        col[2] = {-1,0};
  1193.     static char        letter[] = " ";
  1194.     MFDB            mfdb;
  1195.     int                pxy[8], clip[8];
  1196.     long            bitPlaneSize;
  1197.     char            *addr;
  1198.     short            *image,*mask,*selImage,*selMask;
  1199.     ICONBLK            *iconBlk;
  1200.     int                vdiHandle,planeCount,i,imageCol,maskCol;
  1201.  
  1202.     vdiHandle = VDIhandle;
  1203.     addr    = (char *)parmBlk->pb_parm;
  1204.     iconBlk    = (ICONBLK *)addr;
  1205.     planeCount = (int)(long)iconBlk->ib_pdata;
  1206.     bitPlaneSize = sizeof(short) * ((iconBlk->ib_wicon + 15) / 16L) * (long)iconBlk->ib_hicon;
  1207.  
  1208.     image   = (short *)(addr += sizeof(ICONBLK));
  1209.     mask    = (short *)(addr += planeCount * bitPlaneSize);
  1210.     selImage= (short *)(addr +=              bitPlaneSize);
  1211.     selMask = (short *)(addr += planeCount * bitPlaneSize);
  1212.  
  1213.     if (parmBlk->pb_currstate & SELECTED) {
  1214.         image    = selImage;
  1215.         mask     = selMask;
  1216.         imageCol = (iconBlk->ib_char >>  8) & 0xf;
  1217.         maskCol  = (iconBlk->ib_char >> 12) & 0xf;
  1218.     } else {
  1219.         imageCol = (iconBlk->ib_char >> 12) & 0xf;
  1220.         maskCol  = (iconBlk->ib_char >>  8) & 0xf;
  1221.     }
  1222.  
  1223.     clip[0] = parmBlk->pb_xc;
  1224.     clip[1] = parmBlk->pb_yc;
  1225.     clip[2] = parmBlk->pb_wc;
  1226.     clip[3] = parmBlk->pb_hc;
  1227.     vs_clip(vdiHandle, 1, clip);
  1228.  
  1229.     if (intersect(0,0,parmBlk->pb_w,parmBlk->pb_h,
  1230.                     iconBlk->ib_xicon,iconBlk->ib_yicon,
  1231.                     iconBlk->ib_wicon,iconBlk->ib_hicon,
  1232.                     pxy+4,pxy+5,pxy+6,pxy+7)) {
  1233.         pxy[0] = pxy[1] = 0;
  1234.         pxy[2] = pxy[6]-= 1;
  1235.         pxy[3] = pxy[7]-= 1;
  1236.         pxy[6]+= pxy[4]+= parmBlk->pb_x;
  1237.         pxy[7]+= pxy[5]+= parmBlk->pb_y;
  1238.         mfdb.fd_addr    = mask;
  1239.         mfdb.fd_w        = iconBlk->ib_wicon;
  1240.         mfdb.fd_h        = iconBlk->ib_hicon;
  1241.         mfdb.fd_wdwidth    = (iconBlk->ib_wicon + 15) / 16;
  1242.         mfdb.fd_stand    = 1;
  1243.         mfdb.fd_nplanes    = 1;
  1244.         mfdb.fd_r1        =
  1245.         mfdb.fd_r2        =
  1246.         mfdb.fd_r3        = 0;
  1247.         col[0]          = planeCount == 1 ||
  1248.                           ((iconBlk->ib_char & 0xf00) != 0x100) ?
  1249.                           (iconBlk->ib_char >> 8) & 0xf : WHITE;
  1250.  
  1251.         vrt_cpyfm(vdiHandle,MD_TRANS,pxy,&mfdb,&screen,col);
  1252.         mfdb.fd_addr    = image;
  1253.         mfdb.fd_nplanes    = planeCount;
  1254.         if (planeCount > 1) {
  1255.             mfdb.fd_stand    = 0;
  1256.             vro_cpyfm(vdiHandle,num_planes > 8 ? S_AND_D : S_OR_D,
  1257.                       pxy,&mfdb,&screen);
  1258.         } else {
  1259.             col[0]      = (iconBlk->ib_char >> 12) & 0xf;
  1260.             vrt_cpyfm(vdiHandle,MD_TRANS,pxy,&mfdb,&screen,col);
  1261.         }
  1262.     }
  1263.  
  1264.     if (iconBlk->ib_ptext[0]) {
  1265.         pxy[2] = (pxy[0] = parmBlk->pb_x + iconBlk->ib_xtext) +
  1266.                  iconBlk->ib_wtext - 1;
  1267.         pxy[3] = (pxy[1] = parmBlk->pb_y + iconBlk->ib_ytext) +
  1268.                  iconBlk->ib_htext - 1;
  1269.  
  1270.         vswr_mode(vdiHandle,MD_REPLACE);
  1271.         vsf_color(vdiHandle,maskCol);
  1272.         vsf_interior(vdiHandle,FIS_SOLID);
  1273.         vsf_perimeter(vdiHandle,0);
  1274.         v_bar(vdiHandle,pxy);
  1275.     }
  1276.  
  1277.     if ((letter[0] = iconBlk->ib_char) != '\000' || iconBlk->ib_ptext[0]) {
  1278.         vswr_mode(vdiHandle,MD_TRANS);
  1279.         vst_font(vdiHandle,1);
  1280.         vst_height(vdiHandle,4,&i,&i,&i,&i);
  1281.         vst_color(vdiHandle,imageCol);
  1282.         vst_effects(vdiHandle,0);
  1283.         vst_alignment(vdiHandle,0,5,&i,&i);
  1284.         vst_rotation(vdiHandle,0);
  1285.         if (iconBlk->ib_ptext[0])
  1286.             v_gtext(vdiHandle,pxy[0]+(iconBlk->ib_wtext-
  1287.                     (int)strlen(iconBlk->ib_ptext)*6)/2,
  1288.                     pxy[1]+(iconBlk->ib_htext-6)/2,iconBlk->ib_ptext);
  1289.         if (letter[0])
  1290.             v_gtext(vdiHandle,parmBlk->pb_x+iconBlk->ib_xicon+
  1291.                     iconBlk->ib_xchar,parmBlk->pb_y+iconBlk->ib_yicon+
  1292.                     iconBlk->ib_ychar,letter);
  1293.     }
  1294.  
  1295.     return(parmBlk->pb_currstate & ~SELECTED);
  1296. }
  1297.  
  1298. /*
  1299.  *    Fix resource objects to include customised objects
  1300.  *
  1301.  *    *obj = pointer to object to fix
  1302.  *
  1303.  *    Returns: TRUE on success
  1304.  */
  1305. GLOBAL int fix_object(OBJECT *obj, int sizefix)
  1306. {
  1307.     int images = DARK_SCALING | SCALING, object = 0;
  1308.     USERBLK *ub;
  1309.  
  1310.     do {
  1311.         object++;
  1312.  
  1313.         if (!(obj[object].ob_flags & MENUSIDE) && ((obj[object].ob_type & 0x0F) != G_TITLE)) {
  1314.         switch (obj[object].ob_type & 0xff) {
  1315.             case G_ICON:
  1316.                 if ((obj->ob_type >> 8) == SCALE) {
  1317.                     ICONBLK *icn = obj[object].ob_spec.iconblk;
  1318.  
  1319.                     trans_image(obj);
  1320.                     scale_image(obj, images);
  1321.                     obj[object].ob_height = icn->ib_ytext + icn->ib_htext;
  1322.                 }
  1323.                 break;
  1324.  
  1325.             case G_IMAGE:
  1326.                 if ((obj[object].ob_type >> 8) == SCALE) {
  1327.                     trans_image(obj);
  1328.                     scale_image(obj, images);
  1329.                     obj[object].ob_height = obj[object].ob_spec.bitblk->bi_hl;
  1330.                 }
  1331.                 break;
  1332.  
  1333.             case G_CICON:
  1334.                 obj[object].ob_spec.userblk->ub_parm = (long) obj[object].ob_spec.iconblk;
  1335.                 obj[object].ob_spec.userblk->ub_code = DrawColIcon;
  1336.                 obj[object].ob_type = G_USERDEF;
  1337.                 break;
  1338.  
  1339.             default:
  1340.                 if (((obj[object].ob_type >> 8)==UNDERLINE) ||
  1341.                     ((obj[object].ob_type >> 8)==CUSTOM) ||
  1342.                     ((obj[object].ob_type >> 8)==CYCLEBTN) ||
  1343.                     ((obj[object].ob_type >> 8)==BOXFRAME) ||
  1344.                     ((obj[object].ob_type >> 8)==CUSTBTN) ||
  1345.                     ((obj[object].ob_type >> 8)==DROPDOWN) ||
  1346.                     ((obj[object].ob_type >> 8)==MENULINE) ||
  1347.                     (obj[object].ob_state & DRAW3D)) {
  1348.                         if (ub = calloc(1, sizeof(USERBLK) + sizeof(EXTINFO))) {
  1349.                             EXTINFO *ex = (EXTINFO *) (ub + 1);
  1350.  
  1351.                             switch(obj[object].ob_type & 0xff) {
  1352.                                 case G_TEXT:
  1353.                                     memcpy(ex, obj[object].ob_spec.tedinfo, sizeof(TEDINFO));
  1354.                                     ex->te_thickness = 0;
  1355.                                     break;
  1356.  
  1357.                                 case G_BOXTEXT:
  1358.                                     memcpy(ex, obj[object].ob_spec.tedinfo, sizeof(TEDINFO));
  1359.  
  1360.                                     if (ex->te_thickness < 0) {
  1361.                                         obj[object].ob_width -= ex->te_thickness * 2;
  1362.                                         obj[object].ob_height -= ex->te_thickness * 2;
  1363.                                         obj[object].ob_x += ex->te_thickness;
  1364.                                         obj[object].ob_y += ex->te_thickness;
  1365.                                     }
  1366.                                     break;
  1367.  
  1368.                                 case G_STRING:
  1369.                                     ex->te_ptext = obj[object].ob_spec.free_string;
  1370.                                     ex->te_font = 3;
  1371.                                     ex->te_color.bord_color = ex->te_color.text_color = 1;
  1372.                                     ex->te_thickness = 0;
  1373.                                     break;
  1374.  
  1375.                                 case G_BUTTON:
  1376.                                     ex->te_ptext = obj[object].ob_spec.free_string;
  1377.                                     ex->te_font = 3;
  1378.                                     ex->te_just = 2;
  1379.                                     ex->te_thickness = obj[object].ob_flags & EXIT ? (obj[object].ob_flags & DEFAULT ? -3 : -2) : -1;
  1380.                                     ex->te_color.bord_color = ex->te_color.text_color = 1;
  1381.  
  1382.                                     if (ex->te_thickness < 0) {
  1383.                                         obj[object].ob_width -= ex->te_thickness * 2;
  1384.                                         obj[object].ob_height -= ex->te_thickness * 2;
  1385.                                         obj[object].ob_x += ex->te_thickness;
  1386.                                         obj[object].ob_y += ex->te_thickness;
  1387.                                     }
  1388.                                     break;
  1389.  
  1390.                                 case G_BOX:
  1391.                                     ex->te_ptext = "";
  1392.                                     ex->te_font = 3;
  1393.                                     ex->te_just = 2;
  1394.                                     ex->te_thickness = obj[object].ob_spec.obspec.framesize;
  1395.                                     ex->te_color.bord_color = obj[object].ob_spec.obspec.framecol;
  1396.                                     ex->te_color.text_color = obj[object].ob_spec.obspec.textcol;
  1397.                                     ex->te_color.in_color = obj[object].ob_spec.obspec.interiorcol;
  1398.                                     ex->te_color.fill_ptn = obj[object].ob_spec.obspec.fillpattern;
  1399.                                     if (ex->te_color.fill_ptn == 1)
  1400.                                         ex->te_color.fill_ptn = 0;
  1401.  
  1402.                                     if (ex->te_thickness < 0) {
  1403.                                         obj[object].ob_width -= ex->te_thickness * 2;
  1404.                                         obj[object].ob_height -= ex->te_thickness * 2;
  1405.                                         obj[object].ob_x += ex->te_thickness;
  1406.                                         obj[object].ob_y += ex->te_thickness;
  1407.                                     }
  1408.                                     break;
  1409.  
  1410.                                 case G_IBOX:
  1411.                                     ex->te_ptext = "";
  1412.                                     ex->te_font = 3;
  1413.                                     ex->te_just = 2;
  1414.                                     ex->te_thickness = obj[object].ob_spec.obspec.framesize;
  1415.                                     ex->te_color.bord_color = obj[object].ob_spec.obspec.framecol;
  1416.                                     ex->te_color.text_color = obj[object].ob_spec.obspec.textcol;
  1417.                                     ex->te_color.in_color = obj[object].ob_spec.obspec.interiorcol;
  1418.                                     ex->te_color.fill_ptn = 0;
  1419.  
  1420.                                     if (ex->te_thickness < 0) {
  1421.                                         obj[object].ob_width -= ex->te_thickness * 2;
  1422.                                         obj[object].ob_height -= ex->te_thickness * 2;
  1423.                                         obj[object].ob_x += ex->te_thickness;
  1424.                                         obj[object].ob_y += ex->te_thickness;
  1425.                                     }
  1426.                                     break;
  1427.  
  1428.                                 case G_BOXCHAR:
  1429.                                     ex->te_ptext = "X";
  1430.                                     *ex->te_ptext = obj[object].ob_spec.obspec.character;
  1431.                                     ex->te_font = 3;
  1432.                                     ex->te_just = 2;
  1433.                                     ex->te_thickness = obj[object].ob_spec.obspec.framesize;
  1434.                                     ex->te_color.bord_color = obj[object].ob_spec.obspec.framecol;
  1435.                                     ex->te_color.text_color = obj[object].ob_spec.obspec.textcol;
  1436.                                     ex->te_color.in_color = obj[object].ob_spec.obspec.interiorcol;
  1437.                                     ex->te_color.fill_ptn = obj[object].ob_spec.obspec.fillpattern;
  1438.                                     if (ex->te_color.fill_ptn == 1)
  1439.                                         ex->te_color.fill_ptn = 0;
  1440.  
  1441.                                     if (ex->te_thickness < 0) {
  1442.                                         obj[object].ob_width -= ex->te_thickness * 2;
  1443.                                         obj[object].ob_height -= ex->te_thickness * 2;
  1444.                                         obj[object].ob_x += ex->te_thickness;
  1445.                                         obj[object].ob_y += ex->te_thickness;
  1446.                                     }
  1447.                                     break;
  1448.  
  1449.                                 default:
  1450.                                     break;
  1451.                             }
  1452.  
  1453.                             ex->oldparm = obj[object].ob_spec.userblk;
  1454.                             ex->oldtype = obj[object].ob_type;
  1455.  
  1456.                             ub->ub_parm = (long) ex;
  1457.  
  1458.                             if (((obj[object].ob_state & DRAW3D) || (obj[object].ob_state & MENUTYPE)) &&
  1459.                                 ((obj[object].ob_type >> 8)!=BOXFRAME) &&
  1460.                                 ((obj[object].ob_type >> 8)!=UNDERLINE) &&
  1461.                                 ((obj[object].ob_type >> 8)!=CUSTOM) &&
  1462.                                 ((obj[object].ob_type >> 8)!=CYCLEBTN) &&
  1463.                                 ((obj[object].ob_type >> 8)!=CUSTBTN) &&
  1464.                                 ((obj[object].ob_type >> 8)!=MENULINE) &&
  1465.                                 ((obj[object].ob_type >> 8)!=DROPDOWN)) {
  1466.                                 char *ptr;        /* are put in the upper 8 bits of ob_type! */
  1467.  
  1468.                                 ub->ub_code = draw_specialtext;
  1469.  
  1470.                                 if (((obj[object].ob_type >> 8) != FLYING))
  1471.                                     if ((ptr = strchr(ex->te_ptext, '[')) && *(++ptr))
  1472.                                         obj[object].ob_type = G_USERDEF | ((toupper(*ptr) & 0x7f) << 8);
  1473.                                     else
  1474.                                         obj[object].ob_type = G_USERDEF;
  1475.                                 else
  1476.                                     obj[object].ob_type = (((obj[object].ob_type >> 8) & 0xFF) << 8) + G_USERDEF;
  1477.                             }
  1478.  
  1479.                             switch (obj[object].ob_type >> 8) {
  1480.                                 case UNDERLINE:
  1481.                                     ub->ub_code = draw_underline;
  1482.                                     obj[object].ob_type = (UNDERLINE << 8) + G_USERDEF;
  1483.                                     break;
  1484.  
  1485.                                 case BOXFRAME:
  1486.                                     ub->ub_code = draw_boxframe;
  1487.                                     obj[object].ob_type = (BOXFRAME << 8) + G_USERDEF;
  1488.                                     break;
  1489.  
  1490.                                 case MENULINE:
  1491.                                     ub->ub_code = draw_menuline;
  1492.                                     obj[object].ob_type = (MENULINE << 8) + G_USERDEF;
  1493.                                     break;
  1494.  
  1495.                                 case CUSTOM:
  1496.                                 case CYCLEBTN:
  1497.                                 case DROPDOWN:
  1498.                                 case CUSTBTN: {
  1499.                                         char *ptr = ex->te_ptext;
  1500.                                         int chars = 3;
  1501.         
  1502.                                         while (*ptr)
  1503.                                             if (*ptr++ != '[')
  1504.                                                 chars++;
  1505.                                         if (((obj[object].ob_type >> 8) != CYCLEBTN) &&
  1506.                                             ((obj[object].ob_type >> 8) != DROPDOWN) &&
  1507.                                             ((obj[object].ob_type >> 8) != CUSTBTN))
  1508.                                             obj[object].ob_width = (chars) * gr_cw;
  1509.  
  1510.                                         ub->ub_code = draw_custbutton;
  1511.                                         if ((obj[object].ob_type >> 8) == CUSTOM)
  1512.                                             if ((ptr = strchr(ex->te_ptext, '[')) && *(++ptr))
  1513.                                                 obj[object].ob_type = G_USERDEF | ((toupper(*ptr) & 0x7f) << 8) | 0x8000;
  1514.                                             else
  1515.                                                 obj[object].ob_type = G_USERDEF | 0x8000;
  1516.                                         else {
  1517.                                             if ((obj[object].ob_type >> 8) == CYCLEBTN)
  1518.                                                 obj[object].ob_type = (CYCLEBTN << 8) + G_USERDEF;
  1519.                                             if ((obj[object].ob_type >> 8) == DROPDOWN)
  1520.                                                 obj[object].ob_type = (DROPDOWN << 8) + G_USERDEF;
  1521.                                             if ((obj[object].ob_type >> 8) == CUSTBTN)
  1522.                                                 obj[object].ob_type = (CUSTBTN << 8) + G_USERDEF;
  1523.                                         }
  1524.                                     }
  1525.                                     break;
  1526.                             }
  1527.  
  1528.                             if (AES_VERSION >= 0x0400)
  1529.                                 if (obj[object].ob_state & DRAW3D) {
  1530.                                     if ((ex->oldtype & G_BUTTON) ||
  1531.                                         (ex->oldtype & G_BOXTEXT)) {
  1532.                                         if (ex->te_thickness > 0) {
  1533.                                             obj[object].ob_x -= (abs(ex->te_thickness));
  1534.                                             obj[object].ob_y -= (abs(ex->te_thickness));
  1535.                                             obj[object].ob_width += (abs(ex->te_thickness)) * 2;
  1536.                                             obj[object].ob_height += (abs(ex->te_thickness)) * 2;
  1537.                                         }
  1538.  
  1539.                                         if (ex->te_thickness < 0) {
  1540.                                             obj[object].ob_x += (abs(ex->te_thickness));
  1541.                                             obj[object].ob_y += (abs(ex->te_thickness));
  1542.                                             obj[object].ob_width -= (abs(ex->te_thickness)) * 2;
  1543.                                             obj[object].ob_height -= (abs(ex->te_thickness)) * 2;
  1544.                                         }
  1545.                                     }
  1546. /*                                    obj[object].ob_x += 1;
  1547.                                     obj[object].ob_y += 1;
  1548.                                     obj[object].ob_width -= 2;
  1549.                                     obj[object].ob_height -= 2; */
  1550.                                 }
  1551.  
  1552.                             obj[object].ob_spec.userblk = ub;
  1553.                         } else
  1554.                             return FALSE;
  1555.                 }
  1556.             }
  1557.         }
  1558.     } while(!(obj[object].ob_flags & LASTOB));
  1559.  
  1560.     if (sizefix)
  1561.         position_fix(obj);
  1562.  
  1563.     return TRUE;
  1564. }
  1565.  
  1566.  
  1567.  
  1568. /*
  1569.  *    Restore ("unfix") objects to normal
  1570.  *
  1571.  *    *obj = pointer to object to unfix
  1572.  *
  1573.  *    Returns: nothing
  1574.  */
  1575. GLOBAL void unfix_object(OBJECT *obj)
  1576. {
  1577.     USERBLK *ub;
  1578.     EXTINFO *ex;
  1579.  
  1580.     if (obj->ob_type != G_TITLE) {
  1581.         if (((obj->ob_type >> 8)==UNDERLINE) ||
  1582.             ((obj->ob_type >> 8)==CUSTOM) ||
  1583.             (obj->ob_state & DRAW3D)) {
  1584.                 ub = obj->ob_spec.userblk;
  1585.                 ex = (EXTINFO *) ub->ub_parm;
  1586.  
  1587.                 if (ex != NULL) {
  1588.                     if (ex->te_thickness < 0) {
  1589.                         obj->ob_width += ex->te_thickness * 2;
  1590.                         obj->ob_height += ex->te_thickness * 2;
  1591.                         obj->ob_x -= ex->te_thickness;
  1592.                         obj->ob_y -= ex->te_thickness;
  1593.                     }
  1594.  
  1595.                     obj->ob_spec.userblk = ex->oldparm;
  1596.                     obj->ob_type = ex->oldtype;
  1597.                     free(ub);
  1598.                 }
  1599.         }
  1600.     }
  1601. }
  1602.  
  1603.  
  1604. /*
  1605.  *    Initialise images
  1606.  *
  1607.  *    Returns: nothing
  1608.  */
  1609. GLOBAL void init_images(void)
  1610. {
  1611.     set_images(&radios, &radio_on, &radio_off);
  1612.     set_images(&checks, &box_on, &box_off);
  1613.     set_images(&cycles, &cycle_on, &cycle_off);
  1614.     set_images(&uparrow, &up_on, &up_off);
  1615.     set_images(&dnarrow, &down_on, &down_off);
  1616.     set_images(&lfarrow, &left_on, &left_off);
  1617.     set_images(&rtarrow, &right_on, &right_off);
  1618.     set_images(&dropdown, &dropdown_on, &dropdown_off);
  1619. }